Micron Document
πŸŽ–οΈGitΠ―Ρ€Π°πŸŽ–οΈ


Displaying Rendered β€’ View raw β€’ Download

androidApp/src/google/kotlin/org/meshtastic/app/map/offline/pmtiles/README.md renovate/fastlane-2.x-lockfile (056eed64) Text, 5.46 KB

T383838offline/pmtiles

Overview

Offline vector regions for the Google flavor β€” the counterpart to the MapLibre flavor's native T383838OfflinePack
API, which Google Maps has no equivalent of (its T383838TileProvider is raster-only). Ported from the sibling iOS app's
PMTiles-based offline map (T383838Meshtastic/Helpers/Map/PMTilesExtractor.swift, T383838PMTilesMapView.swift): decode straight
to native map shapes rather than rasterizing, so the offline layer draws in the same coordinate space as node
markers with no compositing seam.

Pipeline

1. T383838PmTilesDailyBuild resolves the current T383838build.protomaps.com/{date}.pmtiles URL (probing backward up to 16
days for the newest one that actually exists).
2. T383838OfflineRegionExtractor enumerates the bbox/zoom-range's tiles (T383838OfflineRegionTileSet) and fetches each one
individually through T383838ch.poole.geo.pmtiles.Reader, which range-requests only that tile's own bytes out of the
multi-gigabyte remote file β€” never the whole thing.
3. T383838OfflineVectorArchive writes the fetched tiles into a local T383838.mbtiles archive (T383838tiles/T383838metadata tables,
T383838format=pbf) β€” the same container T383838MBTilesProvider already reads for raster imports, just vector this time.
Stored uncompressed, not gzip: simpler, at the cost of more disk per tile (see "Deferred" below).
4. T383838OfflineVectorRenderer decodes a rendered tile's T383838water/T383838roads/T383838boundaries layers (T383838VectorTile.kt +
T383838MvtDecoder.kt) into T383838LatLng rings, cached per tile so panning within the same tiles doesn't redecode.
5. T383838OfflineVectorOverlay (a T383838@Composable) draws those rings as native T383838Polygon/T383838Polyline.

Why this shape, not iOS's

β€’ MVT parsing: hand-written T383838@Serializable classes decoded with T383838kotlinx-serialization-protobuf, not a
vendored parser β€” the natural Java vector-tile libraries on GitHub (e.g. T383838ElectronicChartCentre/java-vector-tile)
were never published to Maven Central, and JitPack is a supply-chain trade this ~60-line schema doesn't need to
make. T383838ch.poole.geo.pmtiles:Reader (MIT-licensed) is on Maven Central and handles the PMTiles container format,
so that piece isn't hand-rolled.
β€’ Local storage: a plain T383838.mbtiles SQLite archive, not iOS's own PMTiles-shaped local file. PMTiles' cleverness
(a single HTTP-rangeable remote file) doesn't buy anything once the tiles are already extracted locally; SQLite is
the format this codebase already speaks (T383838MBTilesProvider) and any generic MBTiles tool can open what this writes.
β€’ No geometry simplification/road-stitching pass (iOS's T383838PMTilesMapView.swift:247-321). MVT tiles are already
simplified per zoom level by the source, and Google's classic renderer tolerates more overlays than SwiftUI T383838Map
does β€” legible without it for a first pass, but the win (fewer, longer polylines) is real and worth doing later.
β€’ One HTTP request per tile, not iOS's coalesced-byte-range batching. This is why T383838MAX_TILES_PER_REGION is
2,000 here against iOS's 600,000 β€” at one round trip per tile, anything near that scale would be impractically
slow on a phone connection. Coalescing adjacent tiles' byte ranges into batched requests is the natural way to
raise this cap.

Deferred (tracked here, not hidden)

β€’ Compression: tiles are gunzipped once at download time and stored raw. Storing gzip (like every other MBTiles
vector-tile archive) and decompressing at render time would meaningfully shrink a downloaded region.
β€’ Polygon holes: every ring MVT returns β€” hole or exterior β€” is drawn as its own independent T383838Polygon. A real
lake-with-island therefore double-draws over the island rather than cutting it out. Grouping rings by winding
direction (spec section 4.3.3.3) into proper polygon/hole sets would fix this.
β€’ Auto-activation on connectivity loss: T383838offlineOverlayEnabled is a manual toggle today. Wiring it to
T383838mapNetworkAvailable (from the sibling offline-fallback PR) so a downloaded region draws itself the instant the
network drops β€” matching what that PR already does on MapLibre and what iOS does for its whole offline layer β€” is
a small follow-up once both land; kept manual here so this PR doesn't depend on that one merging first.
β€’ Terrain/hillshade: iOS also offers an offline terrain layer via the same bbox-extraction technique against a
different PMTiles source (Mapterhorn). Not attempted here.

Legal

β€’ T383838ch.poole.geo.pmtiles:Reader β€” MIT license.
β€’ Rendered data is OpenStreetMap-derived via Protomaps; the archive's T383838metadata table and the in-app attribution
both credit "Β© OpenStreetMap contributors, Β© Protomaps" (T383838OfflineRegionExtractor.ATTRIBUTION).
β€’ T383838build.protomaps.com's daily-build endpoint has no documented rate limit or terms distinct from the general
Protomaps project β€” unlike the separate, documented T383838api.protomaps.com hosted tile API. Worth a periodic check
that this is still an acceptable way to source the data; the extraction is a one-time-per-region slice, not
live traffic on every app launch.

Testing

T383838androidApp:testGoogle β€” T383838MvtDecoderTest (hand-encoded protobuf bytes, not a vendored fixture or a round-trip
through the same encoder under test β€” see its own doc comment), T383838WebMercatorTileMathTest, T383838OfflineRegionTileSetTest.
No test drives the network extractor itself; it's a thin loop over already-tested pieces (T383838Reader, T383838MvtDecoder,
T383838OfflineVectorArchive).

Served by rngit 1.5.2 - Generated in 0.06s